package com.xyf.rtmppushdemo

import android.app.Activity
import android.view.View
import com.xyf.rtmppushdemo.camera.CameraType
import com.xyf.rtmppushdemo.listener.LiveStateChangeListener
import com.xyf.rtmppushdemo.listener.OnFrameDataCallback
import com.xyf.rtmppushdemo.param.AudioParam
import com.xyf.rtmppushdemo.param.VideoParam
import com.xyf.rtmppushdemo.stream.AudioStream
import com.xyf.rtmppushdemo.stream.VideoSteam
import com.xyf.rtmppushdemo.stream.VideoSteamFromCamera2

class LivePusher constructor(
    var activity: Activity,
    videoParam: VideoParam,
    audioParam: AudioParam,
    view: View,
    cameraType: CameraType
) : OnFrameDataCallback {
    lateinit var audioStream: AudioStream
    lateinit var videoStream: VideoSteam
    var listener: LiveStateChangeListener? = null

    //error of opening video encoder
    private val ERROR_VIDEO_ENCODER_OPEN = 0x01

    //error of video encoding
    private val ERROR_VIDEO_ENCODE = 0x02

    //error of opening audio encoder
    private val ERROR_AUDIO_ENCODER_OPEN = 0x03

    //error of audio encoding
    private val ERROR_AUDIO_ENCODE = 0x04

    //error of RTMP connecting server
    private val ERROR_RTMP_CONNECT = 0x05

    //error of RTMP connecting stream
    private val ERROR_RTMP_CONNECT_STREAM = 0x06

    //error of RTMP sending packet
    private val ERROR_RTMP_SEND_PACKET = 0x07

    companion object {
        init {
            System.loadLibrary("live_push")
        }
    }

    init {
        nativeInit()
        audioStream = AudioStream(this, audioParam)
        when (cameraType) {
            CameraType.CAMERA2 ->
                videoStream = VideoSteamFromCamera2(this, view, videoParam, activity)
        }


    }
    fun setMute(isMute:Boolean){
        audioStream.setMute(isMute)
    }

    fun startPush(url: String, listener: LiveStateChangeListener) {
        this.listener = listener
        nativeStart(url);
        videoStream.startLive()
        audioStream.startLive()
    }

    fun stopPush() {
        videoStream.stopLive()
        nativeStop()
    }

    fun release() {

    }


    override fun getInputSamples() = getInputSamplesFromNative()

    override fun onAudioFrame(pcm: ByteArray) {
        pushAudio(pcm)
    }

    private fun pushAudio(pcm: ByteArray) {
        nativePushAudio(pcm)
    }

    override fun onAudioCodecInfo(sampleRate: Int, channelCount: Int) {
        setAudioCodecInfo(sampleRate,channelCount)
    }

    private fun setAudioCodecInfo(sampleRate: Int, channelCount: Int) {
        nativeSetAudioCodecInfo(sampleRate,channelCount)
    }

    override fun onVideoFrame(byte: ByteArray, cameraId: Int) {
        pushVideo(byte, cameraId)
    }

    private fun pushVideo(byte: ByteArray, cameraType: Int) {
        nativePushVideo(byte, cameraType)
    }

    override fun onVideoCodecInfo(width: Int, height: Int, frameRate: Int, bitrate: Int) {
        nativeSetVideoCodecInfo(width, height, frameRate, bitrate);
    }

    /**
     * native错误回调函数
     */
    private fun errorFromNative(errorCode: Int) {
        stopPush()
        var msg = ""
        when (errorCode) {
            ERROR_VIDEO_ENCODER_OPEN -> msg =
                activity.getString(R.string.error_video_encoder)
            ERROR_VIDEO_ENCODE -> msg =
                activity.getString(R.string.error_video_encode)
            ERROR_AUDIO_ENCODER_OPEN -> msg =
                activity.getString(R.string.error_audio_encoder)
            ERROR_AUDIO_ENCODE -> msg =
                activity.getString(R.string.error_audio_encode)
            ERROR_RTMP_CONNECT -> msg =
                activity.getString(R.string.error_rtmp_connect)
            ERROR_RTMP_CONNECT_STREAM -> msg =
                activity.getString(R.string.error_rtmp_connect_strem)
            ERROR_RTMP_SEND_PACKET -> msg =
                activity.getString(R.string.error_rtmp_send_packet)
            else -> {}
        }
        listener?.onError(msg)
    }


    private external fun getInputSamplesFromNative(): Int
    private external fun nativeInit()
    private external fun nativePushVideo(byte: ByteArray, cameraType: Int)
    private external fun nativeSetVideoCodecInfo(width: Int, height: Int, fps: Int, bitrate: Int)
    private external fun nativeStart(path: String)
    private external fun nativeStop()
    private external fun nativeSetAudioCodecInfo(sampleRate: Int, channelCount: Int)
    private external fun nativePushAudio(pcm: ByteArray)


}